#ifndef ZMODELER_INC_CURVE_H
#define ZMODELER_INC_CURVE_H

#include "zentity.h"
#include "ucircle3d.h"
#include "ztransf3d.h"

AECMODELER_NAMESPACE_BEGIN


class DllImpExp UeCurve : public UeEntity
{
public:
    UeCurve(UeBody* = NULL);

    // We support these curve types
    //
    enum Type { kUnspecified, kCircle };

    virtual Type     type     () const = NULL;
    virtual UeCurve*   copy     () const = NULL;
    virtual bool     transform(const UeTransf3d&,
                               UeTransf3d::Type  transfType  = UeTransf3d::kUnknown,
                               const UeVector3d& stretchVect = UeVector3d::kNull) = NULL;

    virtual void     print    (FILE* = NULL)         const = NULL;
    virtual void     save     (UeSaveRestoreCallback*) const;
    virtual void     restore  (UeSaveRestoreCallback*)       {}

    UeCurve*           next     () const     { return mpNext; }
    void             setNext  (UeCurve* c)   { mpNext = c;    }

    // Scratch data members
    //
    UeCurve* cptr;
    int    n;     // For print

private:

    UeCurve* mpNext;   // Next curve in the list of all curves of a body

}; // class Curve



class DllImpExp UeUnspecifiedCurve : public UeCurve
{
public:

    UeUnspecifiedCurve(UeBody* b = NULL) : UeCurve(b) {}
    
    virtual Type     type     () const { return kUnspecified; }
    virtual UeCurve*   copy     () const { return new UeUnspecifiedCurve(*this); }
    virtual void     print    (FILE* = NULL) const;

    virtual bool     transform(const UeTransf3d&,
                               UeTransf3d::Type  /*transfType*/  = UeTransf3d::kUnknown,
                               const Vector3d& /*stretchVect*/ = Vector3d::kNull) 
    { return true; }

}; // class UnspecifiedCurve



class DllImpExp UeCircleCurve : public UeCurve
{
public:

    UeCircleCurve() {}
    UeCircleCurve(const UeCircle3d&, int approx, UeBody*); 

    // Return circle definiton data
    //
    const UeTransf3d&  transf   () const { return mTransf;          }
    UePoint3d          origin   () const { return mTransf.origin(); }
    UeLine3d           axis     () const;  
    double           radius   () const { return mRadius; }
    int              approx   () const { return mApprox; }
    UeCircle3d         circle   () const { return UeCircle3d(axis(), mRadius); }

    virtual Type     type     () const { return kCircle; }
    virtual UeCurve*   copy     () const { return new UeCircleCurve(*this); }

    virtual bool     transform(const UeTransf3d&, 
                               UeTransf3d::Type  transfType  = UeTransf3d::kUnknown,
                               const UeVector3d& stretchVect = UeVector3d::kNull);

    virtual void     print    (FILE* = NULL)          const;
    virtual void     save     (UeSaveRestoreCallback*)  const;
    virtual void     restore  (UeSaveRestoreCallback*);

private:

    UeTransf3d mTransf;
    double   mRadius;
    int      mApprox;

}; // class CircleCurve



AECMODELER_NAMESPACE_END
#endif
